home *** CD-ROM | disk | FTP | other *** search
/ Nebula 2 / Nebula Two.iso / SourceCode / GameKit / gamekit-1 / GKSound.m < prev    next >
Text File  |  1995-06-12  |  4KB  |  129 lines

  1.  
  2. // GKSound:  se the header file for info on it's use.
  3.  
  4. #import <gamekit/gamekit.h>
  5. #import <daymisckit/daymisckit.h>
  6. #import <sound/sound.h>
  7.  
  8. @implementation GKSound
  9.  
  10. - setPlayStream:aStream { streamGroup = aStream; return self; }
  11. - _initGKSound
  12. {
  13.     if (!now) now = [[DAYTime alloc] init];
  14.     if (!timeToPlay) timeToPlay = [[DAYTime alloc] init];
  15.     if (!nextPlay) nextPlay = [[DAYTime alloc] initWithCurrentTime];
  16.     return self;
  17. }
  18.  
  19. // overridden init methods: (to assure that _initGKSound is called)
  20. - initFromSoundfile:(const char *)filename
  21. {
  22.     id ret = [super initFromSoundfile:filename];
  23.     [self _initGKSound];
  24.     [self convert];
  25.     return ret;
  26. }
  27.  
  28. - initFromSection:(const char *)sectionName
  29. {
  30.     id ret = [super initFromSection:sectionName];
  31.     [self _initGKSound];
  32.     [self convert];
  33.     return ret;
  34. }
  35.  
  36. - initFromPasteboard:(Pasteboard *)thePboard
  37. {
  38.     id ret = [super initFromPasteboard:thePboard];
  39.     [self _initGKSound];
  40.     [self convert];
  41.     return ret;
  42. }
  43.  
  44. // the new methods:
  45. - setPercentToPlay:(double)percent // how much to play before next play
  46. {
  47.     SNDSoundStruct *mySoundData = [self soundStruct];
  48.     // assuming that we're 16bit 22.050kHz mono sound
  49.     long timeOnStream = (mySoundData->dataSize / 2) * 45.3514739229;
  50.     double usecToPlay = timeOnStream * percent;
  51.     [[timeToPlay init] addMicroseconds:(timeOnStream - usecToPlay)];
  52. #ifdef NOISYDEBUG
  53.     fprintf(stderr, "GKSound:  Play %f percent out of %ld usec (%f usec).\n",
  54.         percent, timeOnStream, usecToPlay);
  55.     fprintf(stderr, "GKSound:  Play when %s (%d) left to go.\n\n",
  56.         [timeToPlay stringValue], [timeToPlay microsecond]);
  57. #endif
  58.     return self;
  59. }
  60.  
  61. - setTimeToPlay:aTime    // how long to play sound before next play
  62. {    // aTime says how long after start of sound play we must wait.
  63.     // we need to find how soon before the sound ends we can start:
  64.     SNDSoundStruct *mySoundData = [self soundStruct];
  65.     // assuming that we're 16bit 22.050kHz mono sound
  66.     long timeOnStream = (mySoundData->dataSize / 2) * 45.3514739229;
  67.     [[[timeToPlay init] addMicroseconds:timeOnStream] subtractTime:aTime];
  68. #ifdef NOISYDEBUG
  69.     fprintf(stderr, "GKSound:  Play after %s (%d).\n",
  70.         [aTime stringValue], [aTime microsecond]);
  71.     fprintf(stderr, "GKSound:  Play when %s (%d) left to go.\n\n",
  72.         [timeToPlay stringValue], [timeToPlay microsecond]);
  73. #endif
  74.     return self;
  75. }
  76.  
  77. - convert
  78. {
  79.     int err;
  80.     if (err = [self convertToFormat:SND_FORMAT_LINEAR_16
  81.             samplingRate:SND_RATE_LOW channelCount:1]) {
  82.         fprintf(stderr, "%s:  GKSound convert error %s\n",
  83.                 [NXApp appName], SNDSoundError(err));
  84.     }
  85.     return self;
  86. }
  87.  
  88. - (int)play // overridden playback method
  89. {
  90.     id temp; // a DAYTime that says when the sound will finish playing.
  91.     
  92.     // check to see if we can be played or not
  93.     [now initWithCurrentTime];
  94. #ifdef NOISYDEBUG
  95.     fprintf(stderr, "GKSound:  Now is: %s (%d)\n", [now stringValue],
  96.         [now microsecond]);
  97.     fprintf(stderr, "GKSound:  Next play at: %s (%d) -- %s\n",
  98.         [nextPlay stringValue], [nextPlay microsecond],
  99.         ([nextPlay isAfter:now] ? "Don't play it." : "Play it."));
  100. #endif
  101.     if ([nextPlay isAfter:now])
  102.         return SND_ERR_NONE; // not time yet:  ignore the play
  103.     
  104.     // do the actual playback:
  105.     if (delegate && [delegate respondsTo:@selector(willPlay:)])
  106.         [delegate willPlay:self]; // we can do this one.
  107.     temp = [streamGroup playSoundStruct:[self soundStruct]];
  108.     // I suppose that if you _really_ need the didPlay, you could set a
  109.     // timed entry to go off when the sound is supposed to finish. *****
  110.     // or hack the GKSoundStream to return/forward the delegate method
  111.     // -soundStream:didCompleteBuffer: which would do the trick (if you
  112.     // have it track the tags; right now it forgets them)
  113.  
  114.     // Calculate when it will be OK to fire off a new sound:
  115.     [nextPlay copyTimeFrom:temp];
  116.     [nextPlay subtractTime:timeToPlay];
  117. #ifdef NOISYDEBUG
  118.     fprintf(stderr, "GKSound:  Sound should end at: %s (%d)\n",
  119.         [temp stringValue], [temp microsecond]);
  120.     fprintf(stderr,
  121.         "GKSound:  Subtract %s (%d) and start next sound at %s (%d)\n\n",
  122.         [timeToPlay stringValue], [timeToPlay microsecond],
  123.         [nextPlay stringValue], [nextPlay microsecond]);
  124. #endif
  125.     return SND_ERR_NONE;
  126. }
  127.  
  128. @end
  129.